package com.visionet.school.app.web.service.dynamic;

import com.visionet.school.app.web.common.utils.PageUtils;
import com.visionet.school.app.web.common.web.WebContextFactory;
import com.visionet.school.app.web.entity.dynamic.Dynamic;
import com.visionet.school.app.web.entity.dynamic.DynamicComment;
import com.visionet.school.app.web.entity.dynamic.DynamicCommentLikes;
import com.visionet.school.app.web.entity.dynamic.vo.DynamicCommentVo;
import com.visionet.school.app.web.entity.enums.MemberType;
import com.visionet.school.app.web.entity.vo.LoginAccountVo;
import com.visionet.school.app.web.repository.dynamic.DynamicCommentLikesRepository;
import com.visionet.school.app.web.repository.dynamic.DynamicCommentRepository;
import com.visionet.school.app.web.repository.dynamic.DynamicLikesRepository;
import com.visionet.school.app.web.repository.dynamic.DynamicRepository;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by hxpeng on 2017/4/21.
 */

@Service
public class DynamicCommentService {

    private static final Logger logger = LoggerFactory.getLogger(DynamicCommentService.class);

    @Autowired
    private DynamicCommentRepository dynamicCommentRepository;

    @Autowired
    private DynamicRepository dynamicRepository;

    @Autowired
    private DynamicCommentLikesRepository dynamicCommentLikesRepository;

    public DynamicCommentVo findOne(String id){
        LoginAccountVo loginAccountVo = WebContextFactory.getWebContext().getLoginAccountVo();
        DynamicComment dynamicComment = dynamicCommentRepository.findOne(id);
        if(dynamicComment != null){
            DynamicCommentVo dynamicCommentVo = new DynamicCommentVo();
            BeanUtils.copyProperties(dynamicComment,dynamicCommentVo);
            int commentLikesCount = dynamicCommentLikesRepository.commentHadLikes(dynamicComment.getId(),loginAccountVo.getMemberId());
            if(commentLikesCount > 0){
                dynamicCommentVo.setHadLikes("1");
            }else{
                dynamicCommentVo.setHadLikes("0");
            }
            return dynamicCommentVo;
        }
        return null;
    }


    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void save(DynamicCommentVo dynamicCommentVo){
        LoginAccountVo loginAccountVo = WebContextFactory.getWebContext().getLoginAccountVo();
        DynamicComment dynamicComment = new DynamicComment();
        BeanUtils.copyProperties(dynamicCommentVo,dynamicComment);
        dynamicComment.setMemberId(loginAccountVo.getMemberId());
        dynamicComment.setMemberName(loginAccountVo.getMemberName());
        dynamicComment.setMemberAvatarPath(loginAccountVo.getMemberAvatarPath());
        dynamicComment.setIsDeleted("0");
        dynamicCommentRepository.save(dynamicComment);

        //动态的评论数量更新
        String dynamicId = dynamicComment.getDynamicId();
        Dynamic dynamic = dynamicRepository.findOne(dynamicId);
        if(dynamic != null){
            int count = dynamicCommentRepository.dynamicCommentCount(dynamicId);
            dynamic.setComments(count);
            dynamicRepository.save(dynamic);
        }

        //如果是楼中楼评论，则父评论回复数量+1
        String parentCommentId = dynamicCommentVo.getParentCommentId();
        if(StringUtils.isNotBlank(parentCommentId)){
            DynamicComment dynamicComment1 = dynamicCommentRepository.findOne(parentCommentId);
            if(dynamicComment1 != null){
                int replyCount = dynamicCommentRepository.commentReplyCount(parentCommentId);
                dynamicComment1.setReply(replyCount);
                dynamicCommentRepository.save(dynamicComment1);
            }
        }
    }


    public Map<String, Object> loadComment(final DynamicCommentVo dynamicCommentVo){
        Page<DynamicCommentVo> objPage = dynamicCommentRepository.loadCommentPage(dynamicCommentVo);
        return PageUtils.getPageMap(objPage);
    }


    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void deletedComment(String commentId){
        DynamicComment dynamicComment = dynamicCommentRepository.findOne(commentId);
        if(dynamicComment != null){
            LoginAccountVo loginAccountVo = WebContextFactory.getWebContext().getLoginAccountVo();
            if(loginAccountVo.getMemberType().equals(MemberType.TEACHER.toKey()) || loginAccountVo.getMemberId().equals(dynamicComment.getMemberId())){
                String dynamicId = dynamicComment.getDynamicId();
                if(StringUtils.isNotBlank(dynamicId)){
                    Dynamic dynamic = dynamicRepository.findOne(dynamicId);
                    if(dynamic != null){
                        int count = dynamicCommentRepository.dynamicCommentCount(dynamicId);
                        dynamic.setComments(count);
                        dynamicRepository.save(dynamic);
                    }
                    dynamicComment.setIsDeleted("1");
                    dynamicCommentRepository.save(dynamicComment);
                }
            }
        }
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void likeComment(String commentId){
        DynamicComment dynamicComment = dynamicCommentRepository.findOne(commentId);
        if(dynamicComment != null){
            LoginAccountVo loginAccountVo = WebContextFactory.getWebContext().getLoginAccountVo();
            int result = dynamicCommentLikesRepository.commentHadLikes(dynamicComment.getId(),loginAccountVo.getMemberId());
            if(result < 1){
                DynamicCommentLikes dynamicCommentLikes = new DynamicCommentLikes();
                dynamicCommentLikes.setCommentId(dynamicComment.getId());
                dynamicCommentLikes.setMemberId(loginAccountVo.getMemberId());
                dynamicCommentLikes.setMemberName(loginAccountVo.getMemberName());
                dynamicCommentLikes.setMemberAvatarPath(loginAccountVo.getMemberAvatarPath());
                dynamicCommentLikes.setIsDeleted("0");
                dynamicCommentLikesRepository.save(dynamicCommentLikes);

                int count = dynamicCommentLikesRepository.dynamicCountLikesCount(dynamicComment.getId());
                dynamicComment.setLikes(count);
                dynamicCommentRepository.save(dynamicComment);
            }
        }
    }


    public Map<String, Object> getCommentInfoPage(final DynamicCommentVo dynamicCommentVo, String sortType){
        List<Sort.Order> orders =new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, sortType));//楼中楼评论按评论时间排序
        Pageable pageable = PageUtils.buildPageRequest(dynamicCommentVo.getPageInfo().getPageNumber(), dynamicCommentVo.getPageInfo().getPageSize(), new Sort(orders));
        Page<DynamicComment> objPage = dynamicCommentRepository.findAll(new Specification<DynamicComment>() {
            public Predicate toPredicate(Root<DynamicComment> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> lstPredicates = new ArrayList<>();
                lstPredicates.add(cb.equal(root.get("parentCommentId"), dynamicCommentVo.getParentCommentId()));
                lstPredicates.add(cb.equal(root.get("isDeleted"), "0"));
                Predicate[] arrayPredicates = new Predicate[lstPredicates.size()];
                return cb.and(lstPredicates.toArray(arrayPredicates));
            }
        }, pageable);
        return PageUtils.getPageMap(objPage);
    }






}
